package com.cwg.dict.ui.rcp.views;

import java.util.Date;

import org.eclipse.jface.viewers.ComboViewer;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.FocusAdapter;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;

/**
* Adds the autocomplete feature to a comboviewer
* Useage: new AutoComplete(comboviewer);
* @author Felipe Lang
*
*/
public class AutoComplete {

	/*
	* Intervalo en milisegundos que deben pasar entre que el usuario presiona
	* una tecla para que se resetee la variable strTyped
	*/
	private static final int	INTERVAL_KEY_PRESSED	= 3000;

	private ComboViewer			comboViewer;

	/*
	* guarda la hora en milisegundos de cuando fu presionada por ultima vez una
	* tecla
	*/
	private long				lastKeyTime				= new Date().getTime();

	/*
	* guarda los caracteres que el usuario va presionando
	*/
	private String				strTyped;

	public AutoComplete(ComboViewer comboViewer) {
		this.comboViewer = comboViewer;
		comboViewer.getCombo().addKeyListener(new KeyAdapter() {
			@Override
			public void keyReleased(KeyEvent e) {
				if (e.keyCode == SWT.DEL) {
					setSelection(null);
				}
				autoCompleteKeyUp(e);
			}

		});

		comboViewer.getCombo().addFocusListener(new FocusAdapter() {

			@Override
			public void focusLost(FocusEvent arg0) {
				autoCompleteLeave();

			}

		});

	}

	public void autoCompleteLeave() {
		// correct casing when leaving combo
		int intFoundIndex = comboViewer.getCombo().indexOf(comboViewer.getCombo().getText());
		comboViewer.getCombo().select(-1);
		comboViewer.getCombo().select(intFoundIndex);
	}

	public void setSelection(Object object) {
		if (object == null) {
			comboViewer.setSelection(null);
		} else {
			comboViewer.setSelection(new StructuredSelection(object));
		}
	}

	private void autoCompleteKeyUp(KeyEvent e) {
		// hora actual en milisegundos
		long now = new Date().getTime();
		if (now - lastKeyTime > INTERVAL_KEY_PRESSED || strTyped == null) {
			strTyped = "";
		}
		lastKeyTime = now;
		// Ignore basic selection keys
		switch (e.keyCode) {
		case SWT.ARROW_RIGHT:
			return;
		case SWT.ARROW_LEFT:
			return;
		case SWT.ARROW_UP:
			strTyped = "";
			return;
		case SWT.ARROW_DOWN:
			strTyped = "";
			return;
		case SWT.CAPS_LOCK:
			return;
		case SWT.BS:
			strTyped = "";
		case SWT.DEL:
			strTyped = "";
			return;
		}

		// guardo lo que el usuario va tipeando
		strTyped += String.valueOf(e.character).toLowerCase();
		int index = comboViewer.getCombo().getSelectionIndex();
		String[] items = comboViewer.getCombo().getItems();
		// busco alguna coicidencia en la lista
		for (int i = 0; i < items.length; i++) {
			String s = items[i].toLowerCase();
			if (s.indexOf(strTyped) == 0) {
				index = i;
				break;
			}
		}
		this.setSelection(comboViewer.getElementAt(index));
	}

}